package com.auth2resource.config;

import com.auth2resource.config.exception.AuthExceptionEntryPoint;
import com.auth2resource.config.exception.CustomAccessDeniedHandler;
import com.auth2resource.config.exception.CustomTokenExtractor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;

/**
 * @ClassName JwtResourceServerConfigurer
 * @Description TODO
 * @Author zl-pc
 * @Date 2020/8/25
 * @Version 1.0
 **/
@ConditionalOnProperty(prefix="jdbc",name = "flag", havingValue = "jwt")
@Configuration
@EnableResourceServer
public class JwtResourceServerConfigurer extends ResourceServerConfigurerAdapter {
    @Autowired
    private TokenStore tokenStore;
    @Autowired
    private CustomTokenExtractor customTokenExtractor;
    @Autowired
    private AuthExceptionEntryPoint authExceptionEntryPoint;
    @Autowired
    private CustomAccessDeniedHandler customAccessDeniedHandler;

    @Value("${oauth.resourceId}")
    public String resourceId;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources
                //设置我这个resource的id, 这个在auth中配置, 这里必须照抄
                .resourceId(resourceId)
               .tokenServices(tokenService())

                //这个貌似是配置要不要把token信息记录在session中
                .stateless(true);
        resources.tokenExtractor(customTokenExtractor)
                .authenticationEntryPoint(authExceptionEntryPoint)
                // .authenticationEntryPoint(new LLGAuthenticationEntryPoint()) //自动续签token信息
                .accessDeniedHandler(customAccessDeniedHandler);
    }
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/login**","/refrech_token**").permitAll()
                //本项目所需要的授权范围,这个scope是写在auth服务的配置里的
                .antMatchers("/**").access("#oauth2.hasScope('app')")

                .and()

                //这个貌似是配置要不要把token信息记录在session中
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    /**
     * 资源服务器令牌解析服务，资源和认证在一起，不用调用远程
     *
     * @return ResourceServerTokenServices
     */
    @Bean
    @Primary
    public ResourceServerTokenServices tokenService() {
        DefaultTokenServices services = new DefaultTokenServices();
        // 必须设置
        services.setTokenStore(tokenStore);
        return services;
    }
}
